package day15;

import java.io.*;
import java.net.Socket;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.*;

public
class AccountSystem {
    static
    Scanner sc=new Scanner(System.in);
    static ScheduledExecutorService es= Executors.newScheduledThreadPool(5);
    static
    List<Account> list=new ArrayList<>();
    public static
    void main(String[] args) {
        one();
    }
    public static void one(){
        while (true){
            System.out.println("---------欢迎来到账号系统--------");
            System.out.println("1.登录");
            System.out.println("2.注册");
            System.out.println("3.退出");
            System.out.println("---------请输入你的选择---------");
            int choice=sc.nextInt();
            switch (choice){
                case 1: login();break;
                case 2: register();break;
                case 3: System.out.println("退出系统");return;
                default: System.out.println("输入有误，请重新输入");
            }
        }
    }
    //如果第一次登录成功可以缓冲登录信息 下次登录直接登录 缓存30s
    public static void login(){
        System.out.println("请输入用户名：");
        String username=sc.next();
        //验证是否登录过
        Account acc=checkCookie(username);
        if(acc!=null) {
            two(acc.username);return;
        }
        System.out.println("请输入密码：");
        String password=sc.next();
        for(Account a:list){
            if(a.username.equals(username)&&a.password.equals(password)){
                System.out.println("是否记住密码？(y/n)，30s后失效");
                String choice=sc.next();
                if("y".equals(choice)){
                    addCookie(username);
                    //创建可周期定长池 30s的首次延迟执行任务

                    es.schedule(()->{
                        removeCookie(username);
                    },30, TimeUnit.SECONDS);
                }
                two(a.username);
                return;
            }
        }
        System.out.println("登录失败");
    }

    private static
    void removeCookie(String username) {
        File f=new File("d://IO//cookie-"+username+".txt");
        if(f.exists()&&f.isFile()) f.delete();
        System.out.println("30s后自动失效");
    }

    private static
    Account checkCookie(String username) {
        try (FileInputStream fis=new FileInputStream("d://IO//cookie-"+username+".txt");
             BufferedReader br=new BufferedReader(new InputStreamReader(fis))
        ){
           String msg= br.readLine();
           //将用户名进行加密 与cookie文件中的内容进行比较
           if(msg!=null&&msg.equals(md5(username))) {
               for (Account a:list) {
                  if(a.username.equals(username)) return a;
               }
           }
        }catch(FileNotFoundException e) {
            System.out.println("首次登录");
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;

    }

    public static void register(){
        System.out.println("请输入用户名：");
        String username=sc.next();
        System.out.println("请输入密码：");
        String password=sc.next();
        list.add(new Account(username,password));
        System.out.println("注册成功");
    }
    public static void two(String username){
        Socket client= null;
        try {
            client = new Socket("192.168.9.176",9998);
//            Server.map.put(username, client);
        } catch (Exception e) {
           e.printStackTrace();
        }
        //进行私聊 读取服务端发送的消息（怎么读不能影响主程序，所以是客户端线程）
        ClientThread c=new ClientThread(client);
        c.start();
        System.out.println(username+"登录成功");
        while (true){
            System.out.println("---------欢迎来到用户界面--------");
            System.out.println("1.聊天功能");
            System.out.println("2.退出登录");
            System.out.println("3.返回上一级");
            int n=sc.nextInt();
            switch (n){
//                case 1: chat(username,client, targetUser);break;
                case 2: removeCookie(username);
                //将客户端socket从map中移除 客户端线程结束
                    c.flag=false;
                    Server.map.remove(username);
                return;
                case 3: return;
                default: System.out.println("输入有误，请重新输入");
            }
        }
    }
    //告诉服务端 我要和谁聊天
    //
    public static
    void chat(String username, Socket client, String targetUser) {
        try {
            OutputStream os=client.getOutputStream();
            //第一次给服务端写入时 要写入 用户名 要聊天的用户名
            os.write((username+","+targetUser+"\n").getBytes());
            while (true){
                System.out.println("请输入要发送的消息：(exit退出聊天)");
                String msg=sc.nextLine();

                if(msg.equals("exit")){
                    os.write(("exit\n").getBytes());
                    Thread.sleep(500);
                    return;
                }
                os.write((username + "," + targetUser + "," + msg + "\n").getBytes());
                System.out.println("消息已发送");

            }
        } catch (IOException |InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void addCookie(String username){
        //将用户名和密码写入到cookie文件中
        try(FileOutputStream fos=new FileOutputStream("d://IO//cookie-"+username+".txt")) {
            fos.write(md5(username).getBytes());
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    public static String md5(String msg) {
        StringBuilder hexString=null;
        try {
// 获取 MessageDigest 类的实例，指定算法为 MD5
            MessageDigest digest = MessageDigest.getInstance("MD5");
// 对字符串进行加密
            byte[] encodedHash = digest.digest(msg.getBytes());
// 将加密后的字节数组转换为十六进制字符串
            hexString = new StringBuilder();
            for (byte b : encodedHash) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return hexString.toString();
    }
}
class Account{
    String username;
    String password;
    public Account(String username, String password) {
        this.username = username;
        this.password = password;
    }
}

